// Boost.Geometry
// Unit Test

// Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include "test_buffer_geo.hpp"
#include "read_from_wkt_file.hpp"

namespace
{

// Source of cases:
// https://thematicmapping.org/downloads/world_borders.php
// https://thetravelporter.com/blog/2016/7/28/from-athens-how-to-make-the-most-of-your-greek-island-hopping
// The selections are generated using "generate_cases = true" in the code below.
std::string const cyclades = "MULTIPOLYGON(((25.838882 36.348053,25.778606 36.345551,25.767773 36.346931,25.738888 36.354996,25.731667 36.362778,25.73027 36.366096,25.73027 36.369713,25.733604 36.377495,25.76722 36.400826,25.771111 36.401932,25.798328 36.389153,25.856937 36.358887,25.856937 36.354996,25.854443 36.352219,25.851662 36.349991,25.847775 36.348885,25.838882 36.348053)),((25.399162 36.39444,25.394722 36.39444,25.391663 36.39666,25.390831 36.403885,25.391388 36.408051,25.393887 36.410828,25.397778 36.411942,25.401665 36.411942,25.406666 36.410553,25.41 36.408333,25.410275 36.404709,25.408604 36.400826,25.406109 36.398041,25.399162 36.39444)),((25.457771 36.333611,25.44722 36.329163,25.420267 36.339008,25.384846 36.344601,25.419437 36.362488,25.430054 36.396801,25.416073 36.430359,25.391371 36.456924,25.370548 36.463608,25.369164 36.46666,25.368889 36.470276,25.371941 36.472488,25.3825 36.477219,25.400272 36.474442,25.421104 36.469994,25.427498 36.465546,25.450829 36.446938,25.453606 36.444443,25.48 36.4161,25.486382 36.408051,25.488888 36.397774,25.484997 36.359154,25.469166 36.343323,25.457771 36.333611)),((24.950275 36.590553,24.945553 36.590553,24.924442 36.59333,24.915276 36.596107,24.856941 36.636383,24.851387 36.641106,24.842499 36.651939,24.84111 36.654999,24.840832 36.658882,24.843887 36.659721,24.855553 36.661942,24.859722 36.662498,24.868889 36.661385,24.938332 36.632774,24.953331 36.621384,24.95472 36.618332,24.962498 36.599159,24.961388 36.594719,24.958332 36.592499,24.950275 36.590553)),((25.089722 36.633881,25.076939 36.631943,25.06694 36.633881,25.063606 36.635818,25.063889 36.639992,25.102219 36.693329,25.141388 36.715828,25.145828 36.71666,25.187775 36.71666,25.188332 36.714722,25.184166 36.705544,25.156666 36.675545,25.135277 36.660553,25.119717 36.650269,25.099716 36.639153,25.089722 36.633881)),((24.413609 36.660271,24.33083 36.649994,24.326942 36.651108,24.324718 36.652771,24.322777 36.659721,24.323055 36.667496,24.340553 36.733055,24.343887 36.740829,24.349163 36.746109,24.352776 36.747772,24.513332 36.767494,24.526943 36.767494,24.535831 36.764717,24.548054 36.759438,24.549442 36.756386,24.550552 36.700554,24.548332 36.691666,24.544441 36.684441,24.540554 36.677773,24.538055 36.674995,24.534721 36.67305,24.476944 36.662773,24.413609 36.660271)),((25.385551 36.651665,25.357777 36.644997,25.342773 36.651665,25.339722 36.65416,25.25861 36.728882,25.261944 36.762772,25.264164 36.766388,25.275829 36.78138,25.27916 36.783333,25.303055 36.789162,25.308048 36.788322,25.326111 36.775826,25.407219 36.717766,25.408333 36.715271,25.39222 36.66111,25.389439 36.652771,25.385551 36.651665)),((24.662777 36.747498,24.658607 36.746666,24.648609 36.746941,24.62833 36.749443,24.624996 36.751389,24.620552 36.756943,24.609722 36.778328,24.611942 36.781662,24.619999 36.788055,24.623886 36.789444,24.64222 36.788887,24.645554 36.787498,24.665276 36.776382,24.670277 36.767494,24.67083 36.759995,24.670277 36.755829,24.665833 36.749718,24.662777 36.747498)),((24.558609 36.775551,24.549721 36.774719,24.544441 36.775276,24.538055 36.779716,24.531666 36.787773,24.522221 36.804993,24.521111 36.812218,24.521111 36.823883,24.522778 36.827774,24.559166 36.848328,24.562496 36.84861,24.591942 36.833885,24.599163 36.823883,24.594997 36.807777,24.592499 36.798882,24.577774 36.781662,24.574718 36.779442,24.558609 36.775551)),((25.459995 36.82222,25.451939 36.820267,25.432774 36.820541,25.420277 36.827766,25.42083 36.83194,25.422497 36.835831,25.474159 36.869164,25.481384 36.849152,25.48333 36.846931,25.48333 36.843323,25.479443 36.833611,25.476944 36.830826,25.459995 36.82222)),((25.826664 36.779709,25.794437 36.764153,25.769444 36.764435,25.761387 36.76722,25.740273 36.777771,25.736938 36.784431,25.738605 36.787491,25.839439 36.840546,25.961941 36.889435,25.976662 36.874161,25.920551 36.836098,25.826664 36.779709)),((25.680832 36.878052,25.672771 36.876389,25.612778 36.880829,25.609997 36.883324,25.609161 36.886658,25.614716 36.89193,25.638882 36.903328,25.651939 36.906097,25.668884 36.899437,25.671661 36.896935,25.683048 36.883881,25.683884 36.880272,25.680832 36.878052)),((25.076664 36.951935,25.071663 36.943871,25.068886 36.946091,25.027222 36.981934,25.024998 36.984711,25.023605 36.999146,25.024162 37.003319,25.025829 37.00721,25.034161 37.014702,25.05444 37.03138,25.057499 37.0336,25.060833 37.035255,25.079163 37.04248,25.083881 37.04248,25.086941 37.040543,25.076664 36.951935)),((24.711941 36.903053,24.708054 36.903053,24.695 36.91555,24.683052 36.930275,24.660275 36.979721,24.639999 37.02916,24.641109 37.042221,24.649719 37.04361,24.661942 37.041382,24.703053 37.029716,24.706665 37.027771,24.740833 36.991661,24.745277 36.986382,24.765274 36.958328,24.766666 36.955276,24.766941 36.951385,24.765831 36.946938,24.761108 36.940826,24.733887 36.918884,24.724163 36.911659,24.711941 36.903053)),((25.834438 37.09304,25.831944 37.090271,25.819443 37.091385,25.801662 37.099442,25.793884 37.103043,25.79055 37.104996,25.783051 37.116653,25.782494 37.119987,25.785 37.121384,25.825554 37.125542,25.837215 37.112488,25.838608 37.109444,25.836105 37.096931,25.834438 37.09304)),((25.250275 37.008324,25.191383 36.973885,25.165833 36.979439,25.152493 36.983887,25.123333 36.994164,25.120274 36.996666,25.10527 37.011658,25.099159 37.023888,25.098328 37.027489,25.098885 37.03138,25.109997 37.057213,25.132771 37.093323,25.151382 37.111931,25.163326 37.121666,25.22361 37.140831,25.268604 37.138611,25.284443 37.128319,25.26833 37.052773,25.264164 37.039162,25.250275 37.008324)),((25.461388 36.919434,25.45277 36.91832,25.436939 36.919991,25.433331 36.922211,25.342773 37.071938,25.341106 37.074997,25.346661 37.086388,25.349716 37.088608,25.496105 37.186378,25.503052 37.189995,25.506943 37.191109,25.535275 37.197777,25.539444 37.198601,25.54472 37.198044,25.548054 37.196106,25.565552 37.180832,25.576664 37.168053,25.583054 37.159988,25.595833 37.135818,25.600552 37.118889,25.600552 37.115273,25.599442 37.106934,25.590275 37.057213,25.587215 37.044167,25.580273 37.015549,25.556664 36.957764,25.554165 36.954987,25.551105 36.952766,25.486382 36.927773,25.461388 36.919434)),((24.535 37.182495,24.534164 37.130554,24.509163 37.112778,24.501389 37.110275,24.494999 37.121666,24.492222 37.123886,24.460278 37.135826,24.456108 37.136108,24.439442 37.132217,24.433609 37.127777,24.421944 37.123886,24.416943 37.124443,24.414719 37.12722,24.415276 37.131104,24.421108 37.156387,24.430832 37.171387,24.441944 37.184166,24.460278 37.195831,24.479443 37.201942,24.492222 37.202774,24.515831 37.201111,24.531109 37.19194,24.533333 37.189163,24.534721 37.186104,24.535 37.182495)),((24.379444 37.305832,24.374722 37.30555,24.370552 37.30722,24.367496 37.309441,24.366665 37.313049,24.367496 37.423607,24.36861 37.427216,24.371944 37.433609,24.398609 37.45916,24.410275 37.46833,24.43861 37.481941,24.442776 37.481667,24.442497 37.474716,24.44083 37.470833,24.430553 37.442215,24.433331 37.43972,24.445274 37.431389,24.463055 37.427498,24.472221 37.426941,24.48222 37.408882,24.483608 37.40583,24.48333 37.398048,24.481667 37.393883,24.44611 37.351387,24.416386 37.325554,24.401665 37.314163,24.383331 37.306938,24.379444 37.305832)),((25.359161 37.407776,25.355553 37.407219,25.328053 37.417763,25.309998 37.469994,25.309166 37.473328,25.310272 37.481667,25.313889 37.488045,25.331661 37.495544,25.349442 37.501389,25.401108 37.493332,25.460548 37.472214,25.463608 37.469719,25.463608 37.465828,25.462215 37.449997,25.461105 37.446381,25.457771 37.444443,25.371105 37.410553,25.359161 37.407776)),((24.952499 37.385551,24.884441 37.363609,24.895275 37.495277,24.891666 37.497215,24.889442 37.5,24.887775 37.503052,24.886944 37.509995,24.889721 37.512497,24.909721 37.509438,24.924999 37.504997,24.933331 37.501389,24.93972 37.496384,24.944164 37.491104,24.951111 37.475273,24.971664 37.406105,24.9725 37.402771,24.969997 37.399719,24.95583 37.387215,24.952499 37.385551)),((25.228333 37.534431,25.20583 37.527222,25.195827 37.527489,25.168327 37.532776,25.113888 37.551102,24.994999 37.639999,24.978886 37.662498,24.974998 37.671944,24.97583 37.675552,24.979721 37.676666,25.010551 37.677498,25.042217 37.676659,25.053883 37.675819,25.074444 37.652489,25.083054 37.649155,25.137215 37.644722,25.184998 37.64193,25.190552 37.641106,25.214165 37.63221,25.238888 37.621941,25.247498 37.614441,25.250275 37.611931,25.255276 37.59166,25.25555 37.583878,25.254993 37.579987,25.231667 37.536385,25.228333 37.534431)),((24.298611 37.526382,24.285275 37.524719,24.27972 37.525551,24.276943 37.528053,24.275276 37.531105,24.269165 37.588882,24.269722 37.593048,24.273609 37.60833,24.276108 37.617218,24.281666 37.627777,24.285831 37.63472,24.298332 37.654999,24.300831 37.657776,24.327221 37.677773,24.334442 37.680832,24.35083 37.68222,24.367222 37.68222,24.370277 37.68222,24.394165 37.673332,24.411388 37.654999,24.411388 37.651382,24.397221 37.619164,24.393055 37.612495,24.381386 37.596939,24.371387 37.585548,24.365833 37.580551,24.31472 37.53611,24.308887 37.531662,24.298611 37.526382)),((24.791664 37.998329,24.962776 37.872498,24.998608 37.767776,24.998886 37.763885,24.997219 37.759995,24.985832 37.733604,24.960278 37.685555,24.947498 37.693054,24.916664 37.715553,24.914444 37.718048,24.873055 37.766388,24.830555 37.814438,24.768608 37.871109,24.765553 37.873604,24.752777 37.878326,24.736942 37.881104,24.716942 37.873329,24.713333 37.872772,24.693607 37.926941,24.690277 37.951385,24.690552 37.955551,24.692219 37.959442,24.696941 37.965828,24.703331 37.969719,24.743889 37.990555,24.778053 37.996941,24.791664 37.998329)))";
std::string const aegeans = "MULTIPOLYGON(((26.025555 38.176941,26.014721 38.149437,25.996105 38.155266,25.971661 38.163605,25.964722 38.167496,25.924995 38.19471,25.864162 38.238319,25.862495 38.241379,25.862495 38.246101,25.864441 38.253876,25.869164 38.263878,25.873882 38.26944,25.906384 38.290276,25.918053 38.294716,25.936665 38.297211,25.942493 38.297211,25.991665 38.34388,25.989716 38.375275,25.989162 38.383881,25.988049 38.387497,25.945827 38.455269,25.939442 38.459435,25.91666 38.468323,25.907776 38.470551,25.89222 38.471931,25.888054 38.47361,25.88166 38.477776,25.860828 38.493889,25.851944 38.500832,25.845833 38.509438,25.827221 38.53611,25.825554 38.539444,25.824997 38.54361,25.843609 38.570541,25.851109 38.578049,25.861664 38.583611,25.869999 38.586388,25.88472 38.588875,26.001389 38.601379,26.138611 38.564995,26.150829 38.556107,26.157776 38.547768,26.159443 38.544434,26.160553 38.538048,26.138882 38.431664,26.13361 38.417496,26.133327 38.408333,26.146111 38.363602,26.161385 38.329163,26.163052 38.326111,26.16111 38.305275,26.160275 38.301384,26.102219 38.246941,26.035553 38.191933,26.027222 38.180275,26.025555 38.176941)),((25.599995 38.531937,25.561939 38.530823,25.527222 38.592766,25.527222 38.596375,25.52916 38.599709,25.53194 38.601944,25.566109 38.60833,25.591942 38.600822,25.610554 38.592499,25.613331 38.589989,25.61694 38.583611,25.620274 38.577209,25.609997 38.542496,25.608887 38.538879,25.60722 38.535553,25.60416 38.533333,25.599995 38.531937)),((24.683052 38.79805,24.683609 38.779716,24.680832 38.776939,24.659164 38.767494,24.646942 38.76416,24.626389 38.765274,24.620552 38.766388,24.616943 38.768326,24.612499 38.773605,24.604721 38.785271,24.598053 38.789719,24.592777 38.789993,24.57111 38.780548,24.566944 38.773605,24.566944 38.769997,24.568886 38.760826,24.553333 38.768326,24.534721 38.783607,24.456665 38.880829,24.450275 38.896942,24.449718 38.946938,24.450832 38.950554,24.452774 38.953888,24.458332 38.962776,24.460831 38.965553,24.477219 38.975555,24.480831 38.977219,24.484722 38.978607,24.489998 38.97805,24.502499 38.972771,24.506107 38.970833,24.577499 38.926109,24.665554 38.824165,24.679165 38.807495,24.681389 38.804718,24.683052 38.79805)),((23.736664 39.074715,23.724442 39.071388,23.709442 39.073883,23.662777 39.086105,23.657776 39.092773,23.590832 39.197495,23.589996 39.200829,23.590832 39.204437,23.593887 39.206665,23.598331 39.207497,23.610832 39.204994,23.783054 39.126106,23.786663 39.124161,23.788887 39.121384,23.789165 39.117775,23.787777 39.114166,23.775276 39.099442,23.770275 39.093605,23.753887 39.083611,23.736664 39.074715)),((23.50861 39.159721,23.45583 39.129997,23.397499 39.143883,23.393608 39.144997,23.392498 39.152222,23.393887 39.159996,23.395832 39.16333,23.444443 39.198883,23.461388 39.208328,23.471664 39.208054,23.486942 39.205276,23.489998 39.203049,23.501389 39.193329,23.506664 39.188332,23.509998 39.18222,23.511944 39.175552,23.512218 39.171661,23.510555 39.163055,23.50861 39.159721)),((23.862499 39.136665,23.855553 39.133049,23.851387 39.13472,23.836109 39.141663,23.833611 39.148048,23.834164 39.152222,23.923611 39.260277,23.949165 39.289162,23.953609 39.289719,23.956665 39.287498,23.956665 39.284996,23.978611 39.267776,23.979443 39.26416,23.978054 39.260277,23.921665 39.178604,23.904442 39.163605,23.862499 39.136665)),((26.377216 39.273598,26.377773 39.26944,26.379993 39.266663,26.383327 39.264709,26.404999 39.253876,26.474716 39.219437,26.528332 39.15416,26.606667 39.053322,26.612221 39.044167,26.618332 39.026108,26.618889 39.021935,26.61694 39.015266,26.614441 39.012497,26.525272 38.974152,26.51833 38.972488,26.450554 38.968323,26.39027 38.9711,26.323887 38.977776,26.187492 39.01722,26.136387 39.040276,26.089165 39.07222,26.086941 39.074997,26.088608 39.078049,26.107777 39.090828,26.112495 39.09166,26.117222 39.090828,26.1675 39.102776,26.276939 39.15638,26.28611 39.167763,26.29277 39.176384,26.293327 39.18055,26.292217 39.184166,26.286942 39.189438,26.261662 39.202492,26.252499 39.20443,26.240555 39.20443,26.235271 39.204163,26.199162 39.201111,26.172497 39.19471,26.165276 39.191109,26.16111 39.184998,26.157776 39.169167,26.153606 39.1586,26.112221 39.112221,26.109718 39.109711,26.084721 39.089722,26.077496 39.086098,26.06805 39.084435,26.062775 39.084717,26.045277 39.089432,25.988106 39.105164,25.889996 39.141106,25.864162 39.153603,25.836662 39.178055,25.833881 39.18055,25.832222 39.183601,25.854717 39.25,25.856384 39.253052,25.861938 39.258041,25.880276 39.271111,25.907776 39.286942,25.923882 39.291939,25.921944 39.284157,25.922497 39.279999,25.924721 39.277222,25.928883 39.275826,25.950272 39.273888,25.978611 39.271935,25.984444 39.27166,26.169167 39.323601,26.172771 39.325554,26.175831 39.327766,26.176388 39.33194,26.17083 39.345551,26.164993 39.367775,26.165833 39.371941,26.178329 39.374985,26.221661 39.383041,26.227493 39.383041,26.323887 39.374435,26.396111 39.341103,26.419994 39.325829,26.414719 39.322495,26.394997 39.305832,26.392494 39.303055,26.379719 39.285271,26.377216 39.273598)),((24.992496 39.466385,24.988888 39.464722,24.985832 39.46611,24.979443 39.478607,24.976387 39.484718,24.969719 39.508049,24.971386 39.516663,24.976665 39.533333,24.978333 39.537216,24.995831 39.558884,25 39.561722,25.001942 39.562752,25.006386 39.563309,25.01527 39.560814,25.027222 39.556084,25.044994 39.545815,25.052498 39.537766,25.053608 39.530823,25.049721 39.523315,25.031384 39.503593,24.992496 39.466385)),((25.441666 40.004715,25.391937 39.952209,25.356667 39.910553,25.351662 39.90416,25.338055 39.87999,25.336388 39.876099,25.338329 39.850822,25.339722 39.847771,25.348885 39.836937,25.351944 39.834435,25.355553 39.832497,25.365273 39.825554,25.373608 39.814438,25.372498 39.810822,25.355827 39.786385,25.338882 39.788879,25.317776 39.793877,25.308331 39.796944,25.300831 39.800819,25.294167 39.805275,25.291943 39.808044,25.266937 39.86805,25.278332 39.888878,25.279442 39.892487,25.27916 39.896378,25.267773 39.909988,25.264996 39.912209,25.25972 39.913605,25.239716 39.913879,25.235271 39.913048,25.228611 39.909157,25.213608 39.896935,25.207771 39.889153,25.181942 39.854713,25.178608 39.846657,25.178608 39.84304,25.201664 39.827492,25.221943 39.810555,25.227219 39.805275,25.226662 39.801384,25.223053 39.799431,25.168327 39.799721,25.162495 39.800819,25.06694 39.842499,25.060833 39.848053,25.05444 39.86055,25.043053 39.963326,25.045277 39.983597,25.049995 39.989716,25.1325 40.005272,25.14027 40.006653,25.226662 40.003052,25.231937 40.002495,25.271938 39.988319,25.368607 40.005829,25.447777 40.0336,25.451382 40.033875,25.453606 40.03138,25.445553 40.00972,25.441666 40.004715)),((25.601662 40.398041,25.566383 40.397774,25.557499 40.401375,25.515831 40.422493,25.490273 40.436935,25.464165 40.454987,25.460831 40.457764,25.443886 40.475822,25.494164 40.496384,25.525555 40.506943,25.54277 40.510544,25.555832 40.511658,25.571384 40.511375,25.579437 40.509995,25.657219 40.49305,25.690273 40.471375,25.694717 40.466103,25.695553 40.462494,25.69611 40.428322,25.695 40.424721,25.69194 40.422493,25.66 40.412491,25.60611 40.398598,25.601662 40.398041)),((24.773331 40.63166,24.766388 40.611382,24.671108 40.578888,24.643608 40.570831,24.642776 40.574165,24.638885 40.579994,24.601665 40.610275,24.59111 40.616661,24.575275 40.624161,24.569443 40.625275,24.533607 40.620552,24.52972 40.621666,24.513611 40.63694,24.511944 40.639999,24.509441 40.658051,24.521664 40.692772,24.533607 40.714165,24.540833 40.723885,24.565552 40.750549,24.596943 40.776939,24.600555 40.778885,24.621387 40.789993,24.641109 40.796661,24.645275 40.797775,24.65472 40.796387,24.696663 40.780548,24.73333 40.765549,24.761387 40.749161,24.763885 40.731941,24.773331 40.63166)))";
std::string const dodecaneses = "MULTIPOLYGON(((26.900555 35.358887,26.880554 35.34333,26.856667 35.350555,26.853333 35.352493,26.850555 35.357498,26.84972 35.372215,26.898052 35.419998,26.901665 35.421661,26.996944 35.434441,27.016109 35.43222,27.019997 35.430832,26.998333 35.40416,26.964443 35.392776,26.900555 35.358887)),((27.157497 35.445831,27.14222 35.399719,27.121666 35.428604,27.067497 35.592773,27.066387 35.596382,27.066109 35.604996,27.067776 35.60833,27.120277 35.666939,27.158333 35.718887,27.162498 35.724716,27.163055 35.728882,27.158607 35.746941,27.158607 35.76944,27.16 35.79583,27.213333 35.825554,27.21722 35.826942,27.228054 35.826385,27.231388 35.82444,27.230831 35.811104,27.215553 35.724716,27.212498 35.718048,27.177498 35.601105,27.202221 35.47805,27.16222 35.451111,27.157497 35.445831)),((27.786663 35.890549,27.781387 35.890274,27.768608 35.893608,27.733055 35.91111,27.730274 35.91333,27.728611 35.916664,27.722221 35.929718,27.719166 35.940826,27.721386 35.94944,27.730831 35.978882,27.740829 36.104439,27.719719 36.1661,27.788883 36.251656,27.803055 36.268326,27.805832 36.270554,27.876106 36.31971,27.895828 36.332222,27.909161 36.339722,28.068333 36.404999,28.107494 36.41861,28.207222 36.44249,28.210831 36.452492,28.212772 36.455544,28.215832 36.457764,28.219166 36.45694,28.225826 36.453049,28.233887 36.441376,28.238049 36.431107,28.206944 36.343597,28.186939 36.299988,28.141388 36.210541,28.122772 36.185822,28.063606 36.111931,28.009163 36.068886,27.956661 36.044991,27.945827 36.034714,27.931664 36.0186,27.906109 35.988052,27.898888 35.975555,27.892776 35.960831,27.865555 35.93222,27.842777 35.913605,27.839443 35.911659,27.799721 35.893326,27.786663 35.890549)),((27.400272 36.372498,27.395554 36.371666,27.317776 36.410828,27.297497 36.422211,27.29472 36.424431,27.29583 36.461098,27.297771 36.464432,27.303055 36.469162,27.354443 36.476662,27.358887 36.475548,27.362221 36.47361,27.44305 36.41111,27.445827 36.4086,27.447495 36.40554,27.44722 36.401665,27.438889 36.391388,27.4175 36.376656,27.413326 36.375542,27.400272 36.372498)),((26.342216 36.506386,26.31805 36.504715,26.312492 36.50499,26.30444 36.507767,26.297218 36.511101,26.288609 36.518044,26.286942 36.521111,26.270554 36.556107,26.262215 36.576935,26.259995 36.58416,26.26083 36.588326,26.262497 36.59166,26.26527 36.59388,26.380276 36.640266,26.385551 36.640549,26.406109 36.633881,26.409443 36.63221,26.458328 36.600822,26.460548 36.598053,26.472218 36.579987,26.471104 36.578331,26.46666 36.576378,26.405827 36.565269,26.35416 36.51944,26.355827 36.511658,26.355827 36.508041,26.342216 36.506386)),((27.854717 36.527222,27.840275 36.524994,27.796661 36.551941,27.79055 36.556107,27.764996 36.574997,27.768887 36.585831,27.812492 36.628052,27.826939 36.641388,27.834438 36.64444,27.851109 36.649155,27.85527 36.650269,27.859718 36.650269,27.865555 36.641388,27.866665 36.637772,27.872772 36.614716,27.876106 36.59861,27.876389 36.594437,27.875275 36.542763,27.873882 36.538879,27.858051 36.528885,27.854717 36.527222)),((26.965832 36.681664,26.971386 36.672211,26.96666 36.672493,26.953053 36.675278,26.946384 36.679153,26.923054 36.7061,26.92083 36.708878,26.91861 36.716103,26.91777 36.755272,26.921944 36.761101,27.060833 36.837212,27.064159 36.838875,27.152493 36.881386,27.168053 36.887215,27.177498 36.888878,27.284443 36.900551,27.340549 36.885277,27.346661 36.881104,27.352776 36.872208,27.355553 36.865273,27.35527 36.858887,27.344166 36.849442,27.329437 36.842766,27.302498 36.837494,27.279442 36.83416,27.243332 36.826935,27.218327 36.81971,27.03611 36.766106,27.028049 36.763611,26.992222 36.751389,26.980553 36.746941,26.974159 36.742775,26.971943 36.740273,26.970551 36.736382,26.966389 36.703606,26.965832 36.681664)),((26.975552 36.924431,26.969719 36.924431,26.946384 36.928055,26.935555 36.932213,26.919167 36.946663,26.881943 37.068886,26.886662 37.073318,26.890831 37.076378,26.960548 37.056107,26.985828 37.044167,27.048328 36.993607,27.049995 36.990555,27.049995 36.949158,27.049438 36.946106,27.04583 36.944153,26.975552 36.924431)),((26.886662 37.096657,26.863888 37.095276,26.853886 37.096657,26.849442 37.097771,26.820553 37.11055,26.769444 37.169434,26.76833 37.173325,26.769161 37.176384,26.778049 37.187775,26.780827 37.189995,26.785553 37.190819,26.820553 37.187218,26.855 37.18277,26.85833 37.181107,26.860554 37.177216,26.872498 37.150551,26.888882 37.109154,26.889721 37.101662,26.889164 37.09861,26.886662 37.096657)),((26.767494 37.186935,26.763611 37.185555,26.759995 37.186661,26.764996 37.196663,26.772221 37.206657,26.774998 37.208878,26.779716 37.209717,26.787495 37.20694,26.788609 37.202209,26.767494 37.186935)),((26.020828 37.514435,25.984161 37.506943,25.980827 37.508881,25.976944 37.514992,25.975552 37.5186,25.974716 37.526932,25.974716 37.53138,25.981937 37.544167,25.984161 37.546944,26.046944 37.616379,26.064442 37.62999,26.06805 37.631943,26.08083 37.635544,26.312492 37.679993,26.351383 37.686378,26.361111 37.686661,26.361664 37.683327,26.360554 37.679436,26.356937 37.672493,26.32333 37.63472,26.308331 37.618889,26.302498 37.614441,26.267494 37.591103,26.214993 37.558884,26.020828 37.514435)),((27.069443 37.711937,27.064159 37.70694,27.060555 37.705269,27.039719 37.702766,26.895554 37.665276,26.81805 37.636658,26.753883 37.691376,26.746384 37.694443,26.711388 37.708321,26.705555 37.708321,26.686939 37.704987,26.649715 37.698318,26.641106 37.696106,26.623333 37.687218,26.620548 37.684998,26.613331 37.680275,26.597218 37.674988,26.593609 37.676941,26.581661 37.685822,26.580555 37.688599,26.571663 37.730553,26.572777 37.734154,26.595833 37.75721,26.598885 37.759438,26.66555 37.790543,26.66972 37.791939,26.729717 37.808044,26.743332 37.811104,26.748608 37.811378,26.988888 37.781937,27.028606 37.77166,27.06694 37.727219,27.069443 37.711937)))";
std::string const ionians = "MULTIPOLYGON(((20.898052 37.805275,20.992496 37.725273,20.998608 37.713882,20.994442 37.698608,20.943333 37.719719,20.924164 37.728607,20.915276 37.731667,20.895832 37.73111,20.87833 37.728333,20.870277 37.726105,20.866943 37.724159,20.84111 37.687218,20.839722 37.683327,20.836109 37.646385,20.831108 37.646385,20.812222 37.651665,20.808609 37.65361,20.713608 37.722771,20.703331 37.732773,20.629997 37.808884,20.62722 37.817497,20.619999 37.847496,20.621944 37.860832,20.628609 37.875549,20.64333 37.898331,20.678333 37.920555,20.699718 37.930275,20.702774 37.928055,20.794167 37.848885,20.863331 37.829163,20.886387 37.814438,20.898052 37.805275)),((20.612499 38.394165,20.680553 38.277496,20.811665 38.121384,20.813332 38.118332,20.81361 38.114441,20.811943 38.105553,20.796665 38.066666,20.7925 38.060272,20.788055 38.059441,20.734997 38.060829,20.557777 38.090553,20.51722 38.102493,20.512775 38.103882,20.377777 38.156662,20.344444 38.174995,20.341389 38.177216,20.339996 38.184441,20.340832 38.196938,20.34222 38.200829,20.35611 38.231941,20.398609 38.325554,20.44083 38.328049,20.442776 38.324997,20.47361 38.309166,20.478611 38.308052,20.483608 38.308327,20.487221 38.309715,20.500553 38.317215,20.507221 38.321106,20.516388 38.327774,20.536388 38.344719,20.54472 38.357498,20.546665 38.361107,20.547497 38.364716,20.550552 38.387772,20.547775 38.394165,20.539719 38.409439,20.534443 38.432777,20.533886 38.436661,20.536942 38.467773,20.539165 38.470551,20.543053 38.471939,20.548332 38.471939,20.562222 38.471107,20.57111 38.468048,20.612499 38.394165)),((20.735554 38.309998,20.719719 38.305275,20.714722 38.306389,20.707222 38.309998,20.699444 38.317497,20.67083 38.35305,20.644722 38.398048,20.615555 38.462494,20.613331 38.469162,20.614166 38.47361,20.648888 38.500275,20.656666 38.501106,20.671108 38.493332,20.706387 38.444717,20.708054 38.44194,20.743332 38.372498,20.761108 38.325272,20.760277 38.321663,20.735554 38.309998)),((20.903053 38.545555,20.899441 38.544167,20.896111 38.545273,20.899166 38.566383,20.914165 38.583328,20.935833 38.604164,20.938889 38.60527,20.941387 38.602493,20.939999 38.593887,20.903053 38.545555)),((20.643608 38.581108,20.54361 38.564438,20.542774 38.567772,20.542221 38.588333,20.557777 38.683884,20.559166 38.688049,20.601665 38.778885,20.643055 38.826942,20.648331 38.832222,20.655552 38.835548,20.701385 38.834717,20.709721 38.832222,20.715832 38.827774,20.729443 38.807495,20.73 38.803886,20.724163 38.634995,20.723053 38.626389,20.720554 38.623604,20.643608 38.581108)),((20.19833 39.174438,20.178055 39.174164,20.165554 39.177498,20.162777 39.179443,20.136665 39.200554,20.124165 39.221382,20.122776 39.232773,20.123608 39.236382,20.133331 39.239441,20.137497 39.240273,20.164997 39.222496,20.187496 39.203049,20.199444 39.186386,20.202221 39.175827,20.19833 39.174438)),((19.926109 39.794441,19.946941 39.783607,19.950554 39.774437,19.950554 39.762215,19.942776 39.744164,19.929165 39.73111,19.926388 39.728607,19.916111 39.722771,19.91222 39.721382,19.875553 39.71611,19.848888 39.705826,19.842499 39.702774,19.839996 39.699997,19.838608 39.695831,19.839443 39.676384,19.846664 39.649162,19.927776 39.477219,19.931942 39.471664,20.018055 39.434441,20.027775 39.431938,20.032776 39.43222,20.048054 39.436943,20.057499 39.442215,20.063332 39.44722,20.067497 39.453606,20.071663 39.453606,20.074718 39.451385,20.121666 39.377777,20.122219 39.373886,20.120277 39.370552,20.114998 39.364998,20.111664 39.363052,20.07972 39.368332,19.884163 39.444443,19.880276 39.446388,19.875275 39.45166,19.854721 39.483887,19.853054 39.486938,19.85083 39.493889,19.846943 39.519722,19.847221 39.535828,19.84972 39.54277,19.844166 39.551941,19.82333 39.576111,19.818333 39.581383,19.806389 39.590553,19.740276 39.624718,19.675831 39.674721,19.673332 39.677216,19.641388 39.744438,19.639999 39.75666,19.650833 39.772499,19.673054 39.793053,19.692219 39.794998,19.696941 39.794441,19.791664 39.790276,19.796665 39.79055,19.803886 39.793884,19.855 39.818329,19.864998 39.81694,19.926109 39.794441)),((19.404163 39.843605,19.393608 39.838333,19.388054 39.838608,19.384163 39.840271,19.377777 39.844719,19.37611 39.847771,19.377777 39.865555,19.378887 39.868607,19.381664 39.871109,19.422497 39.870277,19.427776 39.869995,19.430553 39.867493,19.428608 39.863884,19.404163 39.843605)))";
std::string const crete = "MULTIPOLYGON(((23.858608 35.52166,23.971386 35.514717,23.995552 35.515549,24.03861 35.528717,24.042942 35.530548,24.069611 35.54805,24.071276 35.549553,24.071775 35.551552,24.083332 35.568054,24.078888 35.573608,24.077499 35.57666,24.077774 35.580551,24.079166 35.583611,24.084999 35.588333,24.118053 35.599998,24.12611 35.601944,24.135277 35.599998,24.172222 35.590553,24.180553 35.587219,24.205276 35.54277,24.205276 35.538887,24.203888 35.534996,24.187222 35.509995,24.183887 35.508331,24.169441 35.502777,24.161942 35.500275,24.140553 35.503326,24.128777 35.497383,24.113943 35.498215,24.111441 35.497719,24.109444 35.496719,24.106108 35.493885,24.103109 35.490547,24.102608 35.488384,24.103943 35.486717,24.105942 35.48555,24.174164 35.453606,24.183887 35.451111,24.266109 35.367218,24.271942 35.362495,24.285 35.358604,24.319721 35.351662,24.334442 35.351105,24.348053 35.351662,24.366108 35.35305,24.464722 35.361938,24.484165 35.364716,24.496666 35.366661,24.588608 35.381104,24.600555 35.383606,24.608055 35.386108,24.618053 35.391388,24.629444 35.400551,24.788887 35.408882,24.963333 35.404442,25.046387 35.383888,25.04472 35.379715,25.045277 35.369438,25.048611 35.355827,25.049999 35.352776,25.054996 35.347771,25.063889 35.344719,25.201385 35.334442,25.280552 35.333885,25.302498 35.335548,25.363052 35.335831,25.37722 35.335548,25.387497 35.333328,25.390274 35.330826,25.396942 35.315277,25.40472 35.307777,25.429996 35.294441,25.445274 35.291664,25.463333 35.292496,25.491108 35.298607,25.564442 35.318604,25.618053 35.333328,25.658054 35.342499,25.662777 35.342499,25.766666 35.334717,25.768887 35.33194,25.76722 35.328049,25.765274 35.324715,25.757774 35.316109,25.746109 35.30722,25.732777 35.300278,25.73 35.29805,25.728333 35.294167,25.722775 35.263885,25.728333 35.259163,25.733055 35.257774,25.737221 35.258606,25.739441 35.26194,25.741386 35.269722,25.741386 35.273605,25.742758 35.286358,25.754139 35.282566,25.756208 35.271183,25.755173 35.253593,25.739307 35.231869,25.71833 35.219162,25.71722 35.214722,25.710278 35.174438,25.710831 35.171104,25.717499 35.159164,25.728054 35.141937,25.756664 35.126389,25.779999 35.115555,25.788055 35.112221,25.797497 35.109718,25.808052 35.108055,25.81583 35.109993,25.828053 35.118332,25.866943 35.152222,25.896111 35.176941,26.026665 35.224442,26.030552 35.225555,26.039997 35.225273,26.093052 35.21666,26.111942 35.205276,26.217777 35.240555,26.301109 35.283051,26.290554 35.131104,26.274998 35.087494,26.241943 35.039719,26.237499 35.033607,26.205555 35.02166,26.142498 34.999161,26.138611 34.998055,26.11972 34.992775,26.110832 34.992218,26.10611 34.993332,26.102776 34.995552,26.101109 35.00222,26.101109 35.006104,26.09972 35.009163,26.094997 35.01416,26.086666 35.017494,25.987499 35.033051,25.596943 35.00972,25.589443 35.007217,25.582222 35.00444,25.560833 34.996109,25.557499 34.994438,25.552219 34.989441,25.513332 34.981941,25.504444 34.981384,25.335278 34.984993,25.188053 34.952217,25.016941 34.930832,24.928055 34.93055,24.82111 34.937492,24.752777 34.942215,24.755833 34.950272,24.762775 35.015831,24.759163 35.033051,24.756107 35.046661,24.744164 35.071106,24.739998 35.076385,24.723053 35.090553,24.698608 35.096664,24.693607 35.096939,24.685833 35.094994,24.676941 35.094162,24.638611 35.095276,24.588608 35.096939,24.565552 35.098053,24.560833 35.103333,24.547775 35.119438,24.535553 35.135826,24.526665 35.142494,24.399441 35.186943,24.385555 35.190826,24.196663 35.200272,24.192219 35.200272,24.139721 35.199715,24.10083 35.197777,24.070553 35.190826,24.053333 35.189995,24.048885 35.189995,24.03833 35.191109,24.029442 35.19416,24.026108 35.196106,23.946663 35.221107,23.890274 35.233887,23.824165 35.246666,23.819443 35.246384,23.702221 35.233604,23.694443 35.23111,23.681942 35.224442,23.598331 35.230553,23.593609 35.231941,23.586666 35.235832,23.521111 35.288055,23.519997 35.301941,23.569164 35.526665,23.582497 35.56916,23.583885 35.573051,23.593887 35.592216,23.606388 35.613327,23.608608 35.610832,23.609444 35.607216,23.609722 35.603607,23.609997 35.567497,23.613609 35.526939,23.616108 35.520554,23.618332 35.517776,23.649166 35.499718,23.656944 35.496384,23.666664 35.496109,23.704441 35.501938,23.718887 35.5075,23.724998 35.511665,23.727497 35.514442,23.731941 35.546104,23.730276 35.56316,23.726944 35.574715,23.711388 35.604164,23.708054 35.644165,23.708332 35.648331,23.709442 35.651939,23.71722 35.66555,23.738609 35.685555,23.741665 35.687775,23.748608 35.686386,23.770554 35.671104,23.775555 35.666107,23.775276 35.661942,23.772778 35.659164,23.766941 35.648888,23.766941 35.645271,23.772221 35.613327,23.781944 35.564438,23.784443 35.554443,23.787498 35.548332,23.7925 35.543327,23.799721 35.540276,23.843609 35.523888,23.848331 35.522499,23.858608 35.52166)))";

// Utility function to select geometries within a box, specified and returned in WKT format
template <typename MultiPolygon>
std::string select_within_box(const std::string& wkt, const std::string& wkt_box, bool without_largest = false)
{
    using point_t = typename bg::point_type<MultiPolygon>::type;
    using box_t = bg::model::box<point_t>;
    using polygon_t = typename boost::range_value<MultiPolygon>::type;

    MultiPolygon geometry;
    box_t box;

    bg::read_wkt(wkt, geometry);
    bg::read_wkt(wkt_box, box);

    // Because within is not yet supported for box/polygon, for now it is converted.
    polygon_t poly;
    bg::convert(box, poly);

    if (without_largest)
    {
        std::sort(geometry.begin(), geometry.end(), [](const auto& p1, const auto& p2) { return bg::area(p1) > bg::area(p2); });
        geometry.erase(geometry.begin(), geometry.begin() + 1);
    }

    geometry.erase(std::remove_if(boost::begin(geometry), boost::end(geometry),
        [&poly](const auto& p) { return ! bg::within(p, poly); }), boost::end(geometry));

    std::ostringstream out;
    out << std::setprecision(8) << bg::wkt(geometry);
    return out.str();
}

template <typename Formula, bool Clockwise, typename Point>
void test_geometry(const std::string& base_folder, bool test_all = false, bool generate_cases = false)
{
    using polygon = bg::model::polygon<Point, Clockwise, true>;
    using multi_polygon = bg::model::multi_polygon<polygon>;

    // Because areas can change significantly when another formula is used,
    // use a high tolerance.
    int const points_per_circle = 36;
    ut_settings settings(0.25);

    bg::strategies::buffer::geographic<Formula> strategy;
    bg::strategy::buffer::geographic_join_round<Formula> join(points_per_circle);

    // Dummy strategies, not used for polygon
    bg::strategy::buffer::geographic_side_straight<Formula> _s;
    bg::strategy::buffer::geographic_point_circle<Formula> _c;
    bg::strategy::buffer::end_flat _e;

    if (generate_cases)
    {
        const std::string gr = read_from_wkt_file<multi_polygon>(base_folder + "gr_ll.wkt");

        test_one_geo<multi_polygon, polygon>("gr", gr, strategy, _s, _c, join, _e, 222719122493.0, 10000.0, settings);

        std::cout << "cyclades = " << select_within_box<multi_polygon>(gr, "BOX(24.1395 36.0147,26.1382 38.1464)") << std::endl;
        std::cout << "aegeans = " << select_within_box<multi_polygon>(gr, "BOX(22.6207 38.0017,26.6756 40.9638)") << std::endl;
        std::cout << "dodecaneses = " << select_within_box<multi_polygon>(gr, "BOX(25.8740 35.1906,28.4227 38.0700)") << std::endl;
        std::cout << "ionians = " << select_within_box<multi_polygon>(gr, "BOX(18.9540 37.2072,22.4337 40.6295)") << std::endl;
        std::cout << "crete = " << select_within_box<multi_polygon>(gr, "BOX(23.0592 34.4105,26.5606 35.9347)") << std::endl;

        std::cout << "aegeans = " << aegeans << std::endl;
    }

    test_one_geo<multi_polygon, polygon>("cyclades_20", cyclades, strategy, _s, _c, join, _e, 27664547028.0, 20000.0, settings);
    test_one_geo<multi_polygon, polygon>("aegeans_20", aegeans, strategy, _s, _c, join, _e, 31250495118.0, 20000.0, settings);
    test_one_geo<multi_polygon, polygon>("dodecaneses_20", dodecaneses, strategy, _s, _c, join, _e, 28783570375.0, 20000.0, settings);
    test_one_geo<multi_polygon, polygon>("ionians_20", ionians, strategy, _s, _c, join, _e, 17821402342.0, 20000.0, settings);

    // Crete is tested with negative buffer distances, deflating the polygons
    test_one_geo<multi_polygon, polygon>("crete_20", crete, strategy, _s, _c, join, _e, 132676753.0, -20000.0, settings);

    if (test_all)
    {
        // Because these polygons are large and the buffer algorithm takes time, not all cases are always tested.
        test_one_geo<multi_polygon, polygon>("cyclades_5", cyclades, strategy, _s, _c, join, _e, 8870105175.0, 5000.0, settings);
        test_one_geo<multi_polygon, polygon>("cyclades_10", cyclades, strategy, _s, _c, join, _e, 15955235232.0, 10000.0, settings);

        test_one_geo<multi_polygon, polygon>("aegeans_5", aegeans, strategy, _s, _c, join, _e, 9378944645.0, 5000.0, settings);
        test_one_geo<multi_polygon, polygon>("aegeans_10", aegeans, strategy, _s, _c, join, _e, 15594690692.0, 10000.0, settings);
        test_one_geo<multi_polygon, polygon>("aegeans_50", aegeans, strategy, _s, _c, join, _e, 82410378967.0, 50000.0, settings);

        test_one_geo<multi_polygon, polygon>("dodecaneses_5", dodecaneses, strategy, _s, _c, join, _e, 8422636217.0, 5000.0, settings);
        test_one_geo<multi_polygon, polygon>("dodecaneses_10", dodecaneses, strategy, _s, _c, join, _e, 14519088239.0, 10000.0, settings);
        test_one_geo<multi_polygon, polygon>("dodecaneses_50", dodecaneses, strategy, _s, _c, join, _e, 67815826304.0, 50000.0, settings);

        test_one_geo<multi_polygon, polygon>("ionians_5", ionians, strategy, _s, _c, join, _e, 5865038574.0, 5000.0, settings);
        test_one_geo<multi_polygon, polygon>("ionians_10", ionians, strategy, _s, _c, join, _e, 9831129095.0, 10000.0, settings);

        test_one_geo<multi_polygon, polygon>("crete_5", crete, strategy, _s, _c, join, _e, 4932249738.0, -5000.0, settings);
        test_one_geo<multi_polygon, polygon>("crete_10", crete, strategy, _s, _c, join, _e, 2443181069.0, -10000.0, settings);

        // 23 km is the largest distance (in km) still delivering a polygon when deflating.
        // The result is a polygon with an area of around 2198000 m2 (roughly measured in QGis)
        test_one_geo<multi_polygon, polygon>("crete_23", crete, strategy, _s, _c, join, _e, 2355806.0, -23000.0, settings);
    }
}

}

int test_main(int, char* [])
{
    BoostGeometryWriteTestConfiguration();

    const std::string base_folder = "data/";

    test_geometry<bg::strategy::andoyer, true, bg::model::point<default_test_type, 2, bg::cs::geographic<bg::degree> > >(base_folder);

#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
    test_geometry<bg::strategy::vincenty, true, bg::model::point<default_test_type, 2, bg::cs::geographic<bg::degree> > >(base_folder);
    test_geometry<bg::strategy::thomas, true, bg::model::point<default_test_type, 2, bg::cs::geographic<bg::degree> > >(base_folder);
    test_geometry<bg::strategy::andoyer, true, bg::model::point<long double, 2, bg::cs::geographic<bg::degree> > >(base_folder);
#endif

    return 0;
}
